namespace Roids.SL
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Framework;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;

    public class SpaceShipBlasts : ISceneComponent
    {
        private readonly IList<Blast> _blasts = new List<Blast>();
        private readonly Game _game;

        private readonly SpriteSheet _spriteMap;
        private Texture2D _spriteSheet;

        public SpaceShipBlasts(Game game)
        {
            _game = game;

            _spriteMap = new SpriteSheet(16, 16, 64, 16);
            _spriteMap.InitializeScenes(new[] {4});
        }

        public void LoadContent()
        {
            _spriteSheet = _game.Content.Load<Texture2D>(@"Sprites\Blast");
        }

        public void Update(GameTime gameTime)
        {
            foreach (var blast in _blasts)
            {
                blast.Update(gameTime);

                var bounds = _game.Window.ClientBounds;
                if (blast.Position.X < bounds.X
                    || blast.Position.X > bounds.X + bounds.Width
                    || blast.Position.Y < bounds.Y
                    || blast.Position.Y > bounds.Y + bounds.Height)
                {
                    blast.ReadyToRemove = true;
                }
            }
        }

        public void Draw(GameTime gameTime, SpriteBatch batch)
        {
            //NOTE: this means that allow the blast animations will be in sync, we should change that
            var src = _spriteMap.GetBoundsForFrame(0, gameTime);

            foreach (var blast in _blasts)
            {
                batch.Draw(_spriteSheet, blast.Position, src, Color.White);
            }
        }

        public void CheckCollision(SceneItem item, Action<Blast, Asteroid, CollisionResult> onCollision)
        {
            foreach (var blast in _blasts)
            {
                var collision = blast.CheckCollision(item);
                if (collision.HasCollided)
                {
                    onCollision(blast, (Asteroid) item, collision);
                    break;
                }
            }
        }

        public void FireBlaster(SpaceShip ship)
        {
            var blast = new Blast(_game);

            var trajectory = Vector2.Transform(new Vector2(0, 1), Matrix.CreateRotationZ(ship.Rotation));
            blast.Fire(trajectory, ship.Position);
            ship.FireLaser();
            _blasts.Add(blast);
        }

        public void Clean()
        {
            foreach (var blast in _blasts.ToList())
            {
                if (blast.ReadyToRemove)
                    _blasts.Remove(blast);
            }
        }
    }
}